//------------------------------------------------------------------------------
//
//       Grass.glsl
//
//    Creates 'PointSprite' like grass (billboarded)
//
//------------------------------------------------------------------------------

-- Vertex


layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec2 inAttrib;
layout(location = 2) in vec3 inColor;


out block{
  float grassHeight;
  float jitter;
  vec3 color;
} OUT;


void main()
{
  OUT.grassHeight = inAttrib.x;
  OUT.jitter = inAttrib.y;
  OUT.color = inColor;
  gl_Position = vec4(inPosition,1.0f);
}


--

//------------------------------------------------------------------------------


-- Geometry


layout(points) in;
layout(triangle_strip) out;
layout(max_vertices = 4) out;

in block{
  float grassHeight;
  float jitter;
  vec3 color;
} IN[];

out block{
  vec3 color;
  vec2 texCoord;
} OUT;

uniform mat4 uViewProjMatrix;
uniform vec3 uEyePosition;
uniform float uElapsedTime;

void main()
{
  // Optionally, send NBT for proper rotation
  
  mat4 mvp = uViewProjMatrix;  
  vec3 ptPosition = gl_in[0].gl_Position.xyz;  
  vec3 toEye = (uEyePosition - ptPosition);

  float wind_factor = 0.0f;

  const float wind_lod = 200.0f;
  if (dot(toEye, toEye) < wind_lod*wind_lod) {
    wind_factor = IN[0].jitter * cos(uElapsedTime);
  }

  toEye = normalize(toEye);  
  vec3 up = IN[0].grassHeight * vec3( 0.0f, 1.0f, 0.0f); // -IN[0].normal;
  vec3 right = cross( up, toEye); //IN[0].tangent

  // wind simulation for top vertices
//  float cosine = IN[0].jitter * cos(uElapsedTime);  
  
  //--------------------

  OUT.color = IN[0].color; 
  
  vec3 topLeft = ptPosition + up - right;
  topLeft.xz += wind_factor;
  gl_Position = mvp * vec4( topLeft, 1.0f);
  OUT.texCoord = vec2( 0.0f, 1.0f);
  EmitVertex();
  
  vec3 bottomLeft = ptPosition /*- up*/ - right;
  gl_Position = mvp * vec4( bottomLeft, 1.0f);
  OUT.texCoord = vec2( 0.0f, 0.0f);
  EmitVertex();
  
  vec3 topRight = ptPosition + up + right;
  topRight.xz += wind_factor;
  gl_Position = mvp * vec4( topRight, 1.0f);
  OUT.texCoord = vec2( 1.0f, 1.0f);
  EmitVertex();
  
  vec3 bottomRight = ptPosition /*- up*/ + right;
  gl_Position = mvp * vec4( bottomRight, 1.0f);
  OUT.texCoord = vec2( 1.0f, 0.0f);
  EmitVertex();
    
  EndPrimitive();
}


--

//------------------------------------------------------------------------------


-- Fragment


in block{
  vec3 color;
  vec2 texCoord;
} IN;

layout(location=0) out vec4 fragColor;

uniform sampler2D uDiffuseTex;


void main()
{
  fragColor = texture( uDiffuseTex, IN.texCoord);
  fragColor.rgb *= IN.color;
  if (fragColor.a < 0.25f) { discard; }
}

